﻿#include "ConnectionPool.h"
#include <iostream>

// 测试是否进行正常的crud
void query()
{
    MySqlConn conn;
    conn.connect("root", "123456", "testdb", "192.168.237.128");
    std::string sql = "insert into person values (13, 25, 'man', 'tom')";
    bool flag = conn.update(sql);
    std::cout << "flag value: " << flag << std::endl;

    sql = "select * from person";
    bool flag2 = conn.query(sql);
    std::cout << "flag2 value: " << flag2 << std::endl;
    // 遍历每一行的数据
    while (conn.next()) {
        std::cout << conn.value(0) << ", "
            << conn.value(1) << ", "
            << conn.value(2) << ", "
            << conn.value(3) << std::endl;
    }
}


void opt(int begin, int end)
{
    for (int i = begin; i < end; ++i) {
        MySqlConn conn;
        conn.connect("root", "123456", "testdb", "192.168.237.128");
        char sql[1024] = { 0 };
        sprintf(sql, "insert into person values (%d, 25, 'man', 'tom')", i + 1);
        conn.update(sql);
    }
}

void opt2(ConnectionPool* pool, int begin, int end)
{
    for (int i = begin; i < end; ++i) {
        std::shared_ptr<MySqlConn> conn = pool->getConnection();
        char sql[1024] = { 0 };
        sprintf(sql, "insert into person values (%d, 25, 'man', 'tom')", i + 1);
        conn->update(sql);
    }
}

// 测试单线程不用数据库连接池与用数据库连接池之间的性能差距
void test00()
{
#if 0 
    // 单线程不使用数据库连接池
    // 单线程不使用数据库连接池用时: 70452891700纳秒, 70452毫秒
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    // 插入5000条数据
    opt(0, 5000);
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    auto length = end - begin;
    std::cout << "单线程不使用数据库连接池用时: " << length.count() << "纳秒, " << length.count() / 1000000 << "毫秒" << std::endl;
#else
    // 单线程使用数据库连接池
    // 单线程使用数据库连接池用时: 14039055800纳秒, 14039毫秒
    ConnectionPool* pool = ConnectionPool::getConnectionPool();
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    // 插入5000条数据
    opt2(pool, 0, 5000);
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    auto length = end - begin;
    std::cout << "单线程使用数据库连接池用时: " << length.count() << "纳秒, " << length.count() / 1000000 << "毫秒" << std::endl;
#endif
}

void test01()
{
#if 1
    // 多线程不使用连接池，运行时间：25秒
    MySqlConn conn;
    conn.connect("root", "123456", "testdb", "192.168.237.128");
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    // 5个子线程
    std::thread t1(opt, 0, 1000);
    std::thread t2(opt, 1000, 2000);
    std::thread t3(opt, 2000, 3000);
    std::thread t4(opt, 3000, 4000);
    std::thread t5(opt, 4000, 5000);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    auto length = end - begin;
    std::cout << "多线程不使用连接池，运行时间：" << length.count() / 1000000000 << "秒" << std::endl;
#else  //使用线程池，当写入数据库后，最后会卡那里，不知道为啥
    // 多线程使用连接池，运行时间：5938毫秒
    ConnectionPool* pool = ConnectionPool::getConnectionPool();
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    // 5个子线程
    std::thread t1(opt2, pool, 0, 1000);
    std::thread t2(opt2, pool, 1000, 2000);
    std::thread t3(opt2, pool, 2000, 3000);
    std::thread t4(opt2, pool, 3000, 4000);
    std::thread t5(opt2, pool, 4000, 5000);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    auto length = end - begin;
    std::cout << "多线程使用连接池，运行时间：" << length.count() / 1000000 << "毫秒" << std::endl;
#endif
}

int main()
{
    std::cout << "Hello World!\n";
    // query();
    // test00();
    test01();
}
